home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr22 / cpuid593.zip / CPUID593.ASM < prev    next >
Assembly Source File  |  1993-05-01  |  7KB  |  223 lines

  1.     TITLE    CPUID
  2. ;v5.93    Toad Hall Tweak, 1 Jul 91
  3. ;    - Tightened up code a little, tabified.
  4. ;      I have *no* idea what he did to make the original
  5. ;      CPUID.EXE 6Kb long!  debug enabled?
  6. ;    - Rewritten to .COM format to reduce size further.
  7. ;    We *really* should be returning a magic number as ERRORLEVEL
  8. ;    so a batch file could process accordingly.
  9. ;    David Kirschbaum
  10. ;    kirsch@usasoc.soc.mil
  11.  
  12. CSEG    SEGMENT
  13.     ASSUME    CS:CSEG,DS:CSEG,ES:CSEG
  14.  
  15.     org    100H            ;.COM file
  16.  
  17. cpuid    proc    near
  18.     jmp    start            ;skip over data
  19.  
  20. fp_status    dw    0
  21. id_mess        db    "This system has a$"
  22. fp_8087        db    " and an 8087 math coprocessor$"
  23. fp_80287    db    " and an i287tm math coprocessor$"
  24. fp_80387    db    " and an i387tm math coprocessor$"
  25. c8086        db    "n 8086/8088 microprocessor$"
  26. c286        db    "n 80286 microprocessor$"
  27. c386        db    " i386tm microprocessor$"
  28. c486        db    " i486tm DX microprocessor or i487tm SX math coprocessor$"
  29. c486nfp        db    " i486tm SX microprocessor$"
  30. period        db    ".$",13,10
  31. present_86    db    0    ;v5.92
  32. present_286    db    0    ;v5.92
  33. present_386    db    0    ;v5.92
  34. present_486    db    0    ;v5.92
  35.  
  36. cpuid    endp
  37.  
  38. ;
  39. ; The purpose of this code is to allow the user the ability to identify the
  40. ; processor and coprocessor that is currently in the system.  The algorithm
  41. ; of the program is to first determine the processor id.
  42. ; When that is accomplished, the program continues to then identify whether
  43. ; a coprocessor exists in the system.  If a coprocessor or integrated
  44. ; coprocessor exists, the program will identify the coprocessor id.  If one
  45. ; does not exist, the program then terminates.
  46. ;
  47. start    proc    near
  48.  
  49.     mov    dx,offset id_mess        ; print header message
  50.     mov    ah,9h
  51.     int    21h
  52.  
  53. ;
  54. ;    8086 CPU check
  55. ;    Bits 12-15 are always set on the 8086 processor.
  56. ;
  57.     mov    cx,0F000H        ;handy constant            v5.92
  58.     pushf                ; save EFLAGS
  59.     pop    bx            ; store EFLAGS in BX
  60.     mov    ax,0fffh        ; clear bits 12-15
  61.     and    ax,bx            ;    in EFLAGS
  62.     push    ax            ; store new EFLAGS value on stack
  63.     popf                ; replace current EFLAGS value
  64.     pushf                ; set new EFLAGS
  65.     pop    ax            ; store new EFLAGS in AX
  66.     and    ax,cx    ;0f000h        ; if bits 12-15 are set,    v5.92
  67.     cmp    ax,cx    ;0f000h        ; then CPU is an 8086/8088    v5.92
  68.     mov    dx,offset c8086        ; store 8086/8088 message
  69.     mov    present_86,1        ; turn on 8086/8088 flag
  70.     je    check_fpu        ; if CPU is 8086/8088, check for 8087
  71.  
  72. ;
  73. ;    80286 CPU check
  74. ;    Bits 12-15 are always clear on the 80286 processor.
  75. ;
  76.  
  77.     or    bx,cx    ;0f000h        ; try to set bits 12-15        v5.92
  78.     push    bx
  79.     popf
  80.     pushf
  81.     pop    ax
  82.     and    ax,cx    ;0f000h        ; if bits 12-15 are cleared    v5.92
  83.     mov    dx,offset c286        ; then CPU is an 80286
  84.     mov    present_86,0        ; turn off 8086/8088 flag
  85.     mov    present_286,1        ; turn on 80286 flag
  86.     jz    check_fpu        ; if CPU is 80286, check for 80287
  87.  
  88. ;
  89. ; i386 CPU check
  90. ; The AC bit, bit #18, is a new bit introduced in the EFLAGS register on the
  91. ;  i486 DX CPU to generate alignment faults.  This bit can be set on the
  92. ;  i486 DX CPU, but not on the i386 CPU.
  93.  
  94.  
  95.     mov    bx,sp            ; save current stack pointer to align it
  96.     and    sp,not 3        ; align stack to avoid AC fault
  97.     db    66h
  98.     pushf                ; push original EFLAGS
  99.     db    66h
  100.     pop    ax            ; get original EFLAGS
  101.     db    66h
  102.     mov    cx,ax            ; save original EFLAGS
  103.     db    66h            ; xor EAX,40000h
  104.     xor    ax,0            ; flip AC bit in EFLAGS
  105.     dw    4            ; upper 16-bits of xor constant
  106.     db    66h
  107.     push    ax            ; save for EFLAGS
  108.     db    66h
  109.     popf                ; copy to EFLAGS
  110.     db    66h
  111.     pushf                ; push EFLAGS
  112.     db    66h
  113.     pop    ax            ; get new EFLAGS value
  114.     db    66h
  115.     xor    ax,cx            ; if AC bit cannot be changed, CPU is
  116.     mov    dx,offset c386        ; store i386 message
  117.     mov    present_286,0        ; turn off 80286 flag
  118.     mov    present_386,1        ; turn on i386 flag
  119.     je    check_fpu        ; if CPU is i386, now check for
  120.                     ;       80287/80387 MCP
  121.  
  122. ;
  123. ;    i486 DX CPU / i487 SX MCP and i486 SX CPU checking
  124. ;
  125.     mov    dx,offset c486nfp    ; store 486NFP message
  126.     mov    present_386,0        ; turn off i386 flag
  127.     mov    present_486,1        ; turn on i486 flag
  128.  
  129. ;
  130. ; Co-processor checking begins here for the 8086/80286/i386 CPUs.
  131. ; The algorithm is to determine whether or not the floating-point status
  132. ; and control words can be written to.  If they are not, no coprocessor exists.
  133. ; If the status and control words can be written to, the correct coprocessor
  134. ; is then determined depending on the processor id.  Coprocessor checks are
  135. ; first performed for an 8086, 80286 and a i486 DX CPU.  If the coprocessor id
  136. ; is still undetermined, the system must contain a i386 CPU.  The i386 CPU may
  137. ; work with either an 80287 or an 80387.  The infinity of the coprocessor must
  138. ; be checked to determine the correct coprocessor id.
  139. ;
  140.  
  141. check_fpu:                ; check for 8087/80287/80387
  142.     fninit                ; reset FP status word
  143.     mov    fp_status,5a5ah        ; initialize temp word to non-zero value
  144.     fnstsw  fp_status        ; save FP status word
  145.     mov    ax,fp_status        ; check FP status word
  146. ;v5.92    cmp    al,0
  147.     or    al,al            ; see if correct status with written
  148.     jne    print_one        ; jump if not Valid, no NPX installed
  149.  
  150.     fnstcw  fp_status        ; save FP control word
  151.     mov    ax,fp_status        ; check FP control word
  152.     and    ax,103fh        ; see if selected parts looks OK
  153.     cmp    ax,3fh            ; check that ones and zeroes correctly
  154.                     ; read
  155.     jne    msgterm            ; not valid, no NPX installed    v5.92
  156.  
  157.     cmp    present_486,1        ; check if i486 flag is on
  158.     jne    not_486            ;nope, continue 386 checking    v5.92
  159.                     ;yep, display i486 msg        v5.92
  160.      mov    dx,offset c486        ; store i486 message
  161.      jmp    msgterm            ;display i486 message, terminate v5.92
  162.  
  163. not_486:
  164.     cmp    present_386,1        ; check if i386 flag is on
  165.     jne    print_87_287        ; if i386 flag not on, check NPX for
  166.                     ;    8086/8088/80286
  167.     mov    ah,9h            ; print out i386 CPU ID first
  168.     int    21h
  169.  
  170. ;
  171. ;   80287/80387 check for the i386 CPU
  172. ;
  173.     fld1                ; must use default control from FNINIT
  174.     fldz                ; form infinity
  175.     fdiv                ; 8087/80287 says +inf = -inf
  176.     fld    st            ; form negative infinity
  177.     fchs                ; 80387 says +inf <> -inf
  178.     fcompp                ; see if they are the same
  179.                     ; and remove them
  180.     fstsw    fp_status        ; look at status from FCOMPP
  181.     mov    ax,fp_status
  182.     mov    dx,offset fp_80287    ; store 80287 message
  183.     sahf                ; see if infinities matched
  184.     jz    restore_EFLAGS        ; jump if 8087/80287 is present
  185.      mov    dx,offset fp_80387    ; store 80387 message
  186.  
  187. restore_EFLAGS:
  188.     mov    ah,9h            ; print NPX message
  189.     int    21h
  190.     db    66h
  191.     push    cx            ; push ECX
  192.     db    66h
  193.     popf                ; restore original EFLAGS register
  194.     mov    sp,bx            ; restore original stack pointer
  195.     jmp    short exit
  196.  
  197. print_one:
  198.     jmp    short msgterm        ;print out CPU ID with no NPX    v5.92
  199.  
  200. print_87_287:
  201.     mov    ah,9h            ; print out 8086/8088/80286 first
  202.     int    21h
  203.     cmp    present_86,1        ; if 8086/8088 flag is on
  204.     mov    dx,offset fp_8087    ; store 8087 message
  205.     je    print_fpu
  206.      mov    dx,offset fp_80287    ; else CPU=80286, store 80287 message
  207.  
  208. print_fpu:
  209.     jmp    short msgterm        ;print out NPX            v5.92
  210.  
  211. exit:
  212.     mov    dx,offset period    ; print out a period to end message
  213. msgterm:
  214.     mov    ah,9h
  215.     int    21h
  216.  
  217.     mov    ax,4c00h        ; terminate program
  218.     int    21h
  219. start    endp
  220.  
  221. CSEG    ENDS
  222.     end    cpuid
  223.